import threading
import multiprocessing as mp
import time
from car_base import clientMode
from car_base.car_drive import carDataThreadRun,CarDrive

"""
多进程无人车控制功能测试
包含Value（全局变量）、Lock（进程锁，防止多个进程同时访问一个数据）
可在进程、类、线程中使用Value，并修改Value的值
"""
class DataReadThread(threading.Thread):
    def __init__(self, stopFlag: mp.Value, lock : mp.Lock()):
        threading.Thread.__init__(self)
        self.stopFlag = stopFlag
        self.lock = lock

    def run(self):
        i = 0
        while True:
            self.lock.acquire()
            time.sleep(0.5)
            i += 1
            self.stopFlag.value = i
            if i > 100:
                i = 0
            print("线程在运行！！")
            self.lock.release()

def run1(stopFlag: mp.Value, q_send:mp.Queue, lock : mp.Lock()):
    data_read = DataReadThread(stopFlag, lock)
    # data_read.start()
    car = CarDrive(stopFlag, q_send)
    while True:
        # lock.acquire()  # 锁住
        time.sleep(0.5)
        print("run1:", stopFlag.value)
        car.light(0, 0)
        time.sleep(0.5)
        car.light(1, 1)
        # lock.release()  # 释放

def run2(stopFlag: mp.Value, q_send:mp.Queue, lock : mp.Lock()):
    car = CarDrive(stopFlag, q_send)
    while True:
        # lock.acquire()  # 锁住
        car.go(80, 450)
        car.back(80, 450)
        car.left()
        car.right()
        car.track()
        print("run2:", stopFlag.value)
        # lock.release()  # 释放

def run3(stopFlag:mp.Value, q_send:mp.Queue):
    cline = clientMode()     # 获取连接模式
    carDataThreadRun(cline, stopFlag, q_send) # 启动数据接收和发送线程
    car = CarDrive(stopFlag, q_send, with_flag=False)
    while True:
        time.sleep(0.5)
        car.buzzer(0x01)
        time.sleep(0.5)
        car.buzzer(0x00)
        print("run3:", stopFlag.value)

if __name__ == "__main__":
    stop_flag = mp.Value('i', 10)
    q_send = mp.Queue(2)
    lock = mp.Lock()

    p_run1 = mp.Process(target=run1, args=(stop_flag,q_send, lock))
    p_run2 = mp.Process(target=run2, args=(stop_flag, q_send, lock))
    p_run3 = mp.Process(target=run3, args=(stop_flag, q_send))

    p_run3.start()
    p_run1.start()
    p_run2.start()

    p_run1.join()
    p_run2.join()

    p_run1.terminate()
    p_run2.terminate()
    p_run3.terminate()
